@node System features
@section System features

Scheme48 provides a variety of miscellaneous features built-in to the
system.

@menu

* Miscellaneous features::
* Various utilities::
* Filenames::
* Fluid/dynamic bindings::
* ASCII character encoding::
* Integer enumerations::
* Cells::
* Queues::
* Hash tables::
* Weak references::
* Type annotations::
* Explicit renaming macros::

@end menu

@node Miscellaneous features
@subsection Miscellaneous features

@stindex features
The structure @code{features} provides some very miscellaneous features
in Scheme48.

@cindex immutability
@cindex mutability
@deffn procedure immutable? object @returns{} boolean
@deffnx procedure make-immutable! object @returns{} object
All Scheme objects in Scheme48 have a flag determining whether or not
they may be mutated.  All immediate Scheme objects (@code{()},
@code{#f}, @etc{}) are immutable; all fixnums (small integers) are
immutable; and all stored objects --- vectors, pairs, @etc{} --- may be
mutable.  @code{Immutable?} returns @code{#t} if @var{object} may not
be mutated, and @code{make-immutable!}, a bit ironically, modifies
@var{object} so that it may not be mutated, if it was not already
immutable, and returns it.

@lisp
(immutable? #t)                         @result{} #t
(define p (cons 1 2))
(immutable? p)                          @result{} #f
(car p)                                 @result{} 1
(set-car! p 5)
(car p)                                 @result{} 5
(define q (make-immutable! p))
(eq? p q)                               @result{} #t
(car p)                                 @result{} 5
(immutable? q)                          @result{} #t
(set-car! p 6)                          @error{} immutable pair@end lisp
@end deffn

@deffn procedure string-hash string @returns{} integer-hash-code
Computes a basic but fast hash of @var{string}.

@lisp
(string-hash "Hello, world!")           @result{} 1161@end lisp
@end deffn

@cindex forcing buffered output
@cindex output port buffer forcing
@cindex buffered output forcing
@cindex flushing output buffers
@deffn procedure force-output port @returns{} unspecified
Forces all buffered output to be sent out of @var{port}.

This is identical to the binding of the same name exported by the
@embedref{Ports, @code{i/o} structure}.
@end deffn

@cindex noise output
@deffn procedure current-noise-port @returns{} output-port
The current noise port is a port for sending noise messages that are
inessential to the operation of a program.
@end deffn

@stindex silly
The @code{silly} structure exports a single procedure, implemented as
a VM primitive for the silly reason of efficiency, hence the name of
the structure.@footnote{The author of this manual is not at fault for
this nomenclature.}  It is used in an inner loop of the reader.

@deffn procedure reverse-list->string char-list count @returns{} string
Returns a string of the first @var{count} characters in
@var{char-list}, in reverse.  It is a serious error if @var{char-list}
is not a list whose length is at least @var{count}; the error is not
detected by the VM, so bogus pointers may be involved as a result.
Use this routine with care in inner loops.
@end deffn

@stindex debug-messages
The @code{debug-messages} structure exports a procedure for emitting
very basic debugging messages for low-level problems.

@deffn procedure debug-message item @dots{} @returns{} unspecified
Prints @var{item} @dots{} directly to an error port,@footnote{On Unix,
this is @code{stderr}, the standard I/O error output file.}
eliding buffering and thread synchronization on the Scheme side.
Objects are printed as follows:

@itemize
@item Fixnums (small integers) are written in decimal.

@item Characters are written literally with a @code{#\} prefix.  No
naming translation is performed, so the space and newline characters
are written literally, not as @code{#\space} or @code{#\newline}.

@item Records are written as #@{@var{type-name}@}, where
@var{type-name} is the name of the record's type.

@item Strings and symbols are written literally.

@item Booleans and the empty list are written normally, @ie{} as
@code{#t}, @code{#f}, or @code{()}.

@item Pairs are written as @code{(...)}.

@item Vectors are written as @code{#(...)}.

@item Objects of certain primitive types are written as
#@{@var{type}@}: procedures, templates, locations, code (byte)
vectors, and continuations.@footnote{Continuations here are in the
sense of VM stack frames, not escape procedures as obtained using
@code{call-with-current-continuation}.}

@item Everything else is printed as #@{???@}.
@end itemize
@end deffn

@stindex code-quote
The @code{code-quote} structure exports a variant of @code{quote} that
is useful in some sophisticated macros.

@deffn {special form} code-quote object @returns{} object
Evaluates to the literal value of @var{object}.  This is semantically
identical to @code{quote}, but @var{object} may be anything, and the
compiler will not signal any warnings regarding its value, while such
warnings would be signalled for @code{quote} expressions that do not
wrap readable S-expressions: arbitrary, compound, unreadable data may
be stored in @code{code-quote}.  Values computed at compile-time may
thus be transmitted to run-time code.  However, care should be taken
in doing this.
@end deffn

@node Various utilities
@subsection Various utilities

@stindex util
The @code{util} structure contains some miscellaneous utility routines
extensively used internally in the run-time system.  While they are not
meant to compose a comprehensive library (such as, for example, [SRFI
1]), they were found useful in building the run-time system without
introducing massive libraries into the core of the system.

@cindex unspecific
@cindex unspecified
@deffn procedure unspecific @returns{} unspecific
Returns Scheme48's @dfn{unspecific} token, which is used wherever R5RS
uses the term `unspecific' or `unspecified.'  In this manual, the term
`unspecified' is used to mean that the values returned by a particular
procedure are not specified and may be anything, including a varying
number of values, whereas `unspecific' refers to Scheme48's specific
`unspecific' value that the @code{unspecific} procedure returns.
@end deffn

@deffn procedure reduce kons knil list @returns{} final-knil
Reduces @var{list} by repeatedly applying @var{kons} to elements of
@var{list} and the current @var{knil} value.  This is the fundamental
list recursion operator.

@lisp
(reduce @var{kons} @var{knil}
        (cons @var{elt@sub{1}}
              (cons @var{elt@sub{2}}
                    (@dots{}(cons @var{elt@sub{N}} '())@dots{}))))
    @equiv{}
(@var{kons} @var{elt@sub{1}}
      (@var{kons} @var{elt@sub{2}}
            (@dots{}(@var{kons} @var{elt@sub{N}} @var{knil})@dots{})))@end lisp

Example:

@lisp
(reduce append '() '((1 2 3) (4 5 6) (7 8 9)))
    @result{} (1 2 3 4 5 6 7 8 9)
(append '(1 2 3)
        (append '(4 5 6)
                (append '(7 8 9) '())))
    @result{} (1 2 3 4 5 6 7 8 9)@end lisp
@end deffn

@deffn procedure fold combiner list accumulator @returns{} final-accumulator
Folds @var{list} into an accumulator by repeatedly combining each
element into an accumulator with @var{combiner}.  This is the
fundamental list iteration operator.

@lisp
(fold @var{combiner}
      (list @var{elt@sub{1}} @var{elt@sub{2}} @dots{} @var{elt@sub{N}})
      @var{accumulator})
    @equiv{}
(let* ((accum@sub{1} (@var{combiner} @var{elt@sub{1}} @var{accumulator}))
       (accum@sub{2} (@var{combiner} @var{elt@sub{2}} accum@sub{1}))
       @dots{}
       (accum@sub{N} (@var{combiner} @var{elt@sub{N}} accum@sub{N-1})))
  accum@sub{N})@end lisp

Example:

@lisp
(fold cons '() '(a b c d))
    @result{} (d c b a)
(cons 'd (cons 'c (cons 'b (cons 'a '()))))
    @result{} (d c b a)@end lisp
@end deffn

@deffn procedure fold->2 combiner list accumulator@sub{1} accumulator@sub{2} @returns{} [final-accumulator@sub{1} final-accumulator@sub{2}]
@deffnx procedure fold->3 combiner list accumulator@sub{1} accumulator@sub{2} accumulator@sub{3} @returns{} [final-accumulator@sub{1} final-accumulator@sub{2} final-accumulator@sub{3}]
Variants of @code{fold} for two and three accumulators, respectively.

@lisp
;;; Partition @var{list} by elements that satisfy @var{pred?} and those
;;; that do not.

(fold->2 (lambda (elt satisfied unsatisfied)
           (if (@var{pred?} elt)
               (values (cons elt satisfied) unsatisfied)
               (values satisfied (cons elt unsatisfied))))
         @var{list}
         '() '())@end lisp
@end deffn

@deffn procedure filter predicate list @returns{} filtered-list
Returns a list of all elements in @var{list} that satisfy
@var{predicate}.

@lisp
(filter odd? '(3 1 4 1 5 9 2 6 5 3 5))
    @result{} (3 1 1 5 9 5 3 5)@end lisp
@end deffn

@deffn procedure posq object list @returns{} integer or @code{#f}
@deffnx procedure posv object list @returns{} integer or @code{#f}
@deffnx procedure position object list @returns{} integer or @code{#f}
These find the position of the first element equal to @var{object} in
@var{list}.  @code{Posq} compares elements by @code{eq?}; @code{posv}
compares by @code{eqv?}; @code{position} compares by @code{equal?}.

@lisp
(posq 'c '(a b c d e f))
    @result{} 2
(posv 1/2 '(1 1/2 2 3/2))
    @result{} 1
(position '(d . e) '((a . b) (b . c) (c . d) (d . e) (e . f)))
    @result{} 3@end lisp
@end deffn

@deffn procedure any predicate list @returns{} value or @code{#f}
@deffnx procedure every predicate list @returns{} boolean
@code{Any} returns the value that @var{predicate} returns for the first
element in @var{list} for which @var{predicate} returns a true value;
if no element of @var{list} satisfied @var{predicate}, @code{any}
returns @code{#f}.  @code{Every} returns @code{#t} if every element of
@var{list} satisfies @var{predicate}, or @code{#f} if there exist any
that do not.

@lisp
(any (lambda (x) (and (even? x) (sqrt x)))
     '(0 1 4 9 16))
    @result{} 2
(every odd? '(1 3 5 7 9))
    @result{} #t@end lisp
@end deffn

@deffn procedure sublist list start end @returns{} list
Returns a list of the elements in @var{list} including & after that at
the index @var{start} and before the index @var{end}.

@lisp
(sublist '(a b c d e f g h i) 3 6)      @result{} (d e f)@end lisp
@end deffn

@deffn procedure last list @returns{} value
Returns the last element in @var{list}.  @code{Last}'s effect is
undefined if @var{list} is empty.

@lisp
(last '(a b c))                         @result{} c@end lisp
@end deffn

@deffn procedure insert object list elt< @returns{} list
Inserts @var{object} into the sorted list @var{list}, comparing the
order of @var{object} and each element by @var{elt<}.

@lisp
(insert 3 '(0 1 2 4 5) <)               @result{} (0 1 2 3 4 5)@end lisp
@end deffn

@node Filenames
@subsection Filenames

@stindex filenames
There are some basic filename manipulation facilities exported by the
@code{filenames} structure.@footnote{The facilities Scheme48 provides
are very rudimentary, and they are not intended to act as a coherent
and comprehensive pathname or logical name facility such as that of
Common Lisp.  However, they served the basic needs of Scheme48's build
process when they were originally created.}

@defvr constant *scheme-file-type* @returns{} symbol
@defvrx constant *load-file-type* @returns{} symbol
@code{*Scheme-file-type*} is a symbol denoting the file extension that
Scheme48 assumes for Scheme source files; any other extension, for
instance in the filename list of a structure definition, must be
written explicitly.  @code{*Load-file-type*} is a symbol denoting the
preferable file extension to load files from.  (@code{*Load-file-type*}
was used mostly in bootstrapping Scheme48 from Pseudoscheme or T long
ago and is no longer very useful.)
@end defvr

@deffn procedure file-name-directory filename @returns{} string
@deffnx procedure file-name-nondirectory filename @returns{} string
@code{File-name-directory} returns the directory component of the
filename denoted by the string @var{filename}, including a trailing
separator (on Unix, @code{/}).  @code{File-name-nondirectory} returns
everything but the directory component of the filename denoted by the
string @var{filename}, including the extension.

@lisp
(file-name-directory "/usr/local/lib/scheme48/scheme48.image")
    @result{} "/usr/local/lib/scheme48/"
(file-name-nondirectory "/usr/local/lib/scheme48/scheme48.image")
    @result{} "scheme48.image"
(file-name-directory "scheme48.image")
    @result{} ""
(file-name-nondirectory "scheme48.image")
    @result{} "scheme48.image"@end lisp
@end deffn

@cindex namelists
@dfn{Namelists} are platform-independent means by which to name files.
They are represented as readable S-expressions of any of the following
forms:

@table @code
@item @var{basename}
represents a filename with only a basename and no directory or file
type/extension;

@item (@var{directory} @var{basename} [@var{type}])
represents a filename with a single preceding directory component and
an optional file type/extension; and

@item ((@var{directory} @dots{}) @var{basename} [@var{type}])
represents a filename with a sequence of directory components, a
basename, and an optional file type/extension.
@end table

Each atomic component --- that is, the basename, the type/extension,
and each individual directory component --- may be either a string or
a symbol.  Symbols are converted to the canonical case of the host
operating system by @code{namestring} (on Unix, lowercase); the case of
string components is not touched.

@deffn procedure namestring namelist directory default-type @returns{} string
Converts @var{namelist} to a string in the format required by the host
operating system.@footnote{However, the current standard distribution
of Scheme48 is specific to Unix: the current code implements only Unix
filename facilities.}  If @var{namelist} did not have a directory
component, @var{directory}, a string in the underlying operating
system's format for directory prefixes, is added to the resulting
namestring; and, if @var{namelist} did not have a type/extension,
@var{default-type}, which may be a string or a symbol and which should
@emph{not} already contain the host operating system's delimiter
(usually a dot), is appended to the resulting namestring.

@var{Directory} or @var{default-type} may be @code{#f}, in which case
they are not prefixed or appended to the resulting filename.

@lisp
(namestring 'foo #f #f)                 @result{} "foo"
(namestring 'foo "bar" 'baz)            @result{} "bar/foo.baz"
(namestring '(rts defenum) "scheme" 'scm)
    @result{} "scheme/rts/defenum.scm"
(namestring '((foo bar) baz quux) "zot" #f)
    @result{} "zot/foo/bar/baz.quux"
(namestring "zot/foo/bar/baz.quux" #f "mumble")
    @result{} "zot/foo/bar/baz.quux.mumble"@end lisp
@end deffn

@subsubsection Filename translations

@cindex filename translations
Scheme48 keeps a registry of @dfn{filename translations}, translations
from filename prefixes to the real prefixes.  This allows abstraction
of actual directory prefixes without necessitating running Scheme code
to construct directory pathnames (for example, in configuration files).
Interactively, in the usual command processor, users can set filename
translations with the @command{,translate}; @pxref{Basic commands}.

@deffn procedure translations @returns{} string/string-alist
Returns the alist of filename translations.
@end deffn

@deffn procedure set-translation! from to @returns{} unspecified
Adds a filename prefix translation, overwriting an existing one if one
already existed.
@end deffn

@deffn procedure translate filename @returns{} translated-filename
Translates the first prefix of @var{filename} found in the registry of
translations and returns the translated filename.
@end deffn

@lisp
(set-translation! "s48" "/home/me/scheme/scheme48/scheme")
(translate (namestring '(bcomp frame) "s48" 'scm))
    @result{} "/home/me/scheme/scheme48/scheme/bcomp/frame.scm"
(translate (namestring "comp-packages" "s48" 'scm))
    @result{} "/home/me/scheme/scheme48/scheme/comp-packages.scm"
(translate "s48/frobozz")
    @result{} "/home/me/scheme/scheme48/scheme/frobozz"
(set-translation! "scheme48" "s48")
(translate (namestring '((scheme48 big) filename) #f 'scm))
    @result{} scheme48/big/filename.scm
(translate (translate (namestring '((scheme48 big) filename) #f 'scm)))
    @result{} "/home/me/scheme/scheme48/scheme/big/filename.scm"@end lisp

@cindex @code{=scheme48/}
One filename translation is built-in, mapping @code{=scheme48/} to the
directory of system files in a Scheme48 installation, which on Unix is
typically a directory in @code{/usr/local/lib}.

@lisp
(translate "=scheme48/scheme48.image")
    @result{} /usr/local/scheme48/scheme48.image@end lisp

@node Fluid/dynamic bindings
@subsection Fluid/dynamic bindings

@cindex fluid bindings
@cindex dynamic bindings
@stindex fluids
The @code{fluids} structure provides a facility for dynamically bound
resources, like special variables in Common Lisp, but with first-class,
unforgeable objects.

Every @embedref{Multithreading,thread} in Scheme48 maintains a
@dfn{fluid or dynamic environment}.  It maps @dfn{fluid descriptors} to
their values, much like a lexical environment maps names to their
values.  The dynamic environment is implemented by deep binding and
dynamically scoped.  Fluid variables are represented as first-class
objects for which there is a top-level value and possibly a binding in
the current dynamic environment.  Escape procedures, as created with
Scheme's @code{call-with-current-continuation}, also store & preserve
the dynamic environment at the time of their continuation's capture and
restore it when invoked.

The convention for naming variables that are bound to fluid objects
is to add a prefix of @code{$} (dollar sign); @eg{}, @code{$foo}.

@deffn procedure make-fluid top-level-value @returns{} fluid
Fluid constructor.
@end deffn

@deffn procedure fluid fl @returns{} value
@deffnx procedure set-fluid! fl value @returns{} unspecified
@deffnx procedure fluid-cell-ref fluid-cell @returns{} value
@deffnx procedure fluid-cell-set! fluid-cell value @returns{} unspecified
@code{Fluid} returns the value that the current dynamic environment
associates with @var{fl}, if it has an association; if not, it returns
@var{fl}'s top-level value, as passed to @code{make-fluid} to create
@var{fl}.  @code{Set-fluid!} assigns the value of the association in
the current dynamic environment for @var{fl} to @var{value}, or, if
there is no such association, it assigns the top-level value of
@var{fl} to @var{value}.  Direct assignment of fluids is deprecated,
however, and may be removed in a later release; instead, programmers
should use fluids that are bound to @embedref{Cells, mutable cells}.
@code{Fluid-cell-ref} and @code{fluid-cell-set!} are conveniences for
this; they simply call the corresponding cell operations after
fetching the cell that the fluid refers to by using @code{fluid}.
@end deffn

@deffn procedure let-fluid fluid value thunk @returns{} values
@deffnx procedure let-fluids fluid@sub{0} value@sub{0} fluid@sub{1} value@sub{1} @dots{} thunk @returns{} values
These dynamically bind their fluid arguments to the corresponding value
arguments and apply @var{thunk} with the new dynamic environment,
restoring the old one after @var{thunk} returns and returning the value
it returns.
@end deffn

@lisp
(define $mumble (make-fluid 0))

(let ((a (fluid $mumble))
      (b (let-fluid $mumble 1
           (lambda () (fluid $mumble))))
      (c (fluid $mumble))
      (d (let-fluid $mumble 2
           (lambda ()
             (let-fluid $mumble 3
               (lambda () (fluid $mumble)))))))
  (list a b c d))
    @result{} (0 1 0 3)

(let ((note (lambda (when)
              (display when)
              (display ": ")
              (write (fluid $mumble))
              (newline))))
  (note 'initial)
  (let-fluid $mumble 1 (lambda () (note 'let-fluid)))
  (note 'after-let-fluid)
  (let-fluid $mumble 1
    (lambda ()
      (note 'outer-let-fluid)
      (let-fluid $mumble 2 (lambda () (note 'inner-let-fluid)))))
  (note 'after-inner-let-fluid)
  ((call-with-current-continuation
     (lambda (k)
       (lambda ()
         (let-fluid $mumble 1
           (lambda ()
             (note 'let-fluid-within-cont)
             (let-fluid $mumble 2
               (lambda () (note 'inner-let-fluid-within-cont)))
             (k (lambda () (note 'let-fluid-thrown)))))))))
  (note 'after-throw))
    @print{} initial: 0
    @print{} let-fluid: 1
    @print{} after-let-fluid: 0
    @print{} outer-let-fluid: 1
    @print{} inner-let-fluid: 2
    @print{} let-fluid-within-cont: 1
    @print{} inner-let-fluid-within-cont: 2
    @print{} let-fluid-thrown: 0
    @print{} after-throw: 0@end lisp

@node ASCII character encoding
@subsection ASCII character encoding

@stindex ascii
These names are exported by the @code{ascii} structure.

@deffn procedure char->ascii char @returns{} ascii-integer
@deffnx procedure ascii->char ascii-integer @returns{} character
These convert characters to and from their integer ASCII encodings.
@code{Char->ascii} and @code{ascii->char} are similar to R5RS's
@code{char->integer} and @code{integer->char}, but they are guaranteed
to use the ASCII encoding.  Scheme48's @code{integer->char} and
@code{char->integer} deliberately do not use the ASCII encoding to
encourage programmers to make use of only what R5RS guarantees.

@lisp
(char->ascii #\a)                       @result{} 97
(ascii->char 97)                        @result{} #\a@end lisp
@end deffn

@defvr constant ascii-limit @returns{} integer
@defvrx constant ascii-whitespaces @returns{} ascii-integer-list
@code{Ascii-limit} is an integer that is one greater than the highest
number that @code{char->ascii} may return or @code{ascii->char} will
accept.  @code{Ascii-whitespaces} is a list of the integer encodings of
all characters that are considered whitespace: space (32), horizontal
tab (9), line-feed/newline (10), vertical tab (11), form-feed/page (12),
and carriage return (13).
@end defvr

@node Integer enumerations
@subsection Integer enumerations

@stindex enumerated
Scheme48 provides a facility for @dfn{integer enumerations}, somewhat
akin to C enums.  The names described in this section are exported by
the @code{enumerated} structure.

@strong{Note:} These enumerations are @emph{not} compatible with the
@embedref{Enumerated/finite types and sets, enumerated/finite type
facility}.

@deffn syntax define-enumeration enumeration-name (enumerand-name @dots{})
Defines @var{enumeration-name} to be a static enumeration.  (Note that
it is @emph{not} a regular variable.  It is actually a macro, though its
exact syntax is not exposed; it must be exported with the
@embedref{Static type system, @code{:syntax} type}.)
@var{Enumeration-name} thereafter may be used with the enumeration
operators described below.
@end deffn

@deffn syntax enum enumeration-name enumerand-name @returns{} enumerand-integer
@deffnx syntax components enumeration-name @returns{} component-vector
@code{Enum} expands to the integer value represented symbolically by
@var{enumerand-name} in the enumeration @var{enumeration-name} as
defined by @code{define-enumeration}.  @code{Components} expands to a
literal vector of the components in @var{enumeration-name} as defined
by @code{define-enumeration}.  In both cases, @var{enumerand-name} must
be written literally as the name of the enumerand; see
@code{name->enumerand} for extracting an enumerand's integer given a
run-time symbol naming an enumerand.
@end deffn

@deffn syntax enumerand->name enumerand-integer enumeration-name @returns{} symbol
@deffnx syntax name->enumerand enumerand-name enumeration-name @returns{} integer-enumerand
@code{Enumerand->name} expands to a form that evaluates to the symbolic
name that the integer value of the expression @var{enumerand-integer}
is mapped to by @var{enumeration-name} as defined by
@code{define-enumeration}.  @code{Name->enumerand} expands to a form
that evaluates to the integer value of the enumerand in
@var{enumeration-name} that is represented symbolically by the value of
the expression @var{enumerand-name}.
@end deffn

@stindex enum-case
The @code{enum-case} structure provides a handy utility of the same
name for dispatching on enumerands.

@deffn syntax enum-case
@lisp
(enum-case @var{enumeration-name} @var{key}
  ((@var{enumerand-name} @dots{}) @var{body})
  @dots{}
  [(else @var{else-body})])@end lisp
Matches @var{key} with the clause one of whose names maps in
@var{enumeration-name} to the integer value of @var{key}.  @var{Key}
must be an exact, non-negative integer.  If no matching clause is
found, and @var{else-body} is present, @code{enum-case} will evaluate
@var{else-body}; if @var{else-body} is not present, @code{enum-case}
will return an unspecific value.
@end deffn

Examples:

@lisp
(define-enumeration foo
  (bar
   baz))

(enum foo bar)                          @result{} 0
(enum foo baz)                          @result{} 1

(enum-case foo (enum foo bar)
  ((baz) 'x)
  (else  'y))
    @result{} y

(enum-case foo (enum foo baz)
  ((bar) 'a)
  ((baz) 'b))
    @result{} b

(enumerand->name 1 foo)                 @result{} baz
(name->enumerand 'bar foo)              @result{} 0
(components foo)                        @result{} #(bar baz)@end lisp

@c Include the sections on the various kinds of data structures.

@include system/data.texi

@node Type annotations
@subsection Type annotations

@cindex type system loopholes
@cindex loopholes in the type system
@stindex loopholes
Scheme48 allows optional type annotations with the @code{loophole}
special form from the @code{loopholes} structure.

@deffn syntax loophole type expression @returns{} values
This is exactly equivalent in semantics to @var{expression}, except the
static type analyzer is informed that the whole expression has the type
@var{type}.  For details on the form of @var{type}, @pxref{Static type
system}.
@end deffn

Type annotations can be used for several different purposes:

@itemize @bullet
@item
simply to give more information to the static type analyzer;

@item
to work as a simple abstract data type facility: passing a type name
that does not already exist creates a new disjoint value type; and

@item
to prevent the type system from generating warnings in the rare cases
where it would do so incorrectly, such as in the @code{primitive-cwcc},
@code{primitive-catch}, and @code{with-continuation} devices (to be
documented in a later edition of this manual).
@end itemize

To see an example of the second use, see @file{rts/jar-defrecord.scm}
in Scheme48's source tree.

@strong{Note:} Type annotations do @emph{not} damage the safety of
Scheme's type system.  They affect only the static type analyzer, which
does not change run-time object representations; it only checks type
soundness of code and generates warnings for programs that would cause
run-time type errors.

@node Explicit renaming macros
@subsection Explicit renaming macros

@cindex low-level macros
@cindex macros, low-level
@cindex unhygienic macros
@cindex macros, unhygienic
Scheme48 supports a simple low-level macro system based on explicitly
renaming identifiers to preserve hygiene.  The macro system is
well-integrated with the module system; @pxref{Macros in concert with
modules}.

@dfn{Explicit renaming} macro transformers operate on simple
S-expressions extended with @dfn{identifiers}, which are like symbols
but contain more information about lexical context.  In order to
preserve that lexical context, transformers must explicitly call a
@dfn{renamer} procedure to produce an identifier with the proper scope.
To test whether identifiers have the same denotation, transformers are
also given an identifier comparator.

The facility provided by Scheme48 is almost identical to the explicit
renaming macro facility described in [Clinger 91].@footnote{For the
sake of avoiding any potential copyright issues, the paper is not
duplicated here, and instead the author of this manual has written the
entirety of this section.}  It differs only by the @code{transformer}
keyword, which is described in the paper but not used by Scheme48, and
in the annotation of auxiliary names.

@deffn syntax define-syntax name transformer [aux-names]
Introduces a derived syntax @var{name} with the given transformer,
which may be an explicit renaming transformer procedure, a pair whose
car is such a procedure and whose cdr is a list of auxiliary
identifiers, or the value of a @code{syntax-rules} expression.  In the
first case, the added operand @var{aux-names} may, and usually should
except in the case of local (non-exported) syntactic bindings, be a
list of all of the auxiliary top-level identifiers used by the macro.
@end deffn

Explicit renaming transformer procedures are procedures of three
arguments: an input form, an identifier renamer procedure, and an
identifier comparator procedure.  The input form is the whole form of
the macro's invocation (including, at the car, the identifier whose
denotation was the syntactic binding).  The identifier renamer accepts
an identifier as an argument and returns an identifier that is
hygienically renamed to refer absolutely to the identifier's denotation
in the environment of the macro's definition, not in the environment of
the macro's usage.  In order to preserve hygiene of syntactic
transformations, macro transformers must call this renamer procedure
for any literal identifiers in the output.  The renamer procedure is
referentially transparent; that is, two invocations of it with the same
arguments in terms of @code{eq?} will produce the same results in the
sense of @code{eq?}.

For example, this simple transformer for a @code{swap!} macro is
incorrect:

@lisp
(define-syntax swap!
  (lambda (form rename compare)
    (let ((a (cadr  form))
          (b (caddr form)))
      `(LET ((TEMP ,a))
         (SET! ,a ,b)
         (SET! ,b TEMP)))))@end lisp

@noindent
The introduction of the literal identifier @code{temp} into the output
may conflict with one of the input variables if it were to also be
named @code{temp}: @code{(swap! temp foo)} or @code{(swap! bar temp)}
would produce the wrong result.  Also, the macro would fail in another
very strange way if the user were to have a local variable named
@code{let} or @code{set!}, or it would simply produce invalid output if
there were no binding of @code{let} or @code{set!} in the environment
in which the macro was used.  These are basic problems of abstraction:
the user of the macro should not need to know how the macro is
internally implemented, notably with a @code{temp} variable and using
the @code{let} and @code{set!} special forms.

Instead, the macro must hygienically rename these identifiers using
the renamer procedure it is given, and it should list the top-level
identifiers it renames (which cannot otherwise be extracted
automatically from the macro's definition):

@lisp
(define-syntax swap!
  (lambda (form rename compare)
    (let ((a (cadr  form))
          (b (caddr form)))
      `(,(rename 'LET) ((,(rename 'TEMP) ,a))
         (,(rename 'SET!) ,a ,b)
         (,(rename 'SET!) ,b ,(rename 'TEMP)))))
  (LET SET!))@end lisp

However, some macros are unhygienic by design, @ie{} they insert
identifiers into the output intended to be used in the environment of
the macro's usage.  For example, consider a @code{loop} macro that
loops endlessly, but binds a variable named @code{exit} to an escape
procedure to the continuation of the @code{loop} expression, with
which the user of the macro can escape the loop:

@lisp
(define-syntax loop
  (lambda (form rename compare)
    (let ((body (cdr form)))
      `(,(rename 'CALL-WITH-CURRENT-CONTINUATION)
         (,(rename 'LAMBDA) (EXIT)      ; Literal, unrenamed EXIT.
           (,(rename 'LET) ,(rename 'LOOP) ()
             ,@@body
             (,(rename 'LOOP)))))))
  (CALL-WITH-CURRENT-CONTINUATION LAMBDA LET))@end lisp

Note that macros that expand to @code{loop} must also be unhygienic;
for instance, this na@"{@dotless{i}}ve definition of a
@code{loop-while} macro is incorrect, because it hygienically renames
@code{exit} automatically by of the definition of @code{syntax-rules},
so the identifier it refers to is not the one introduced
unhygienically by @code{loop}:

@lisp
(define-syntax loop-while
  (syntax-rules ()
    ((LOOP-WHILE test body ...)
     (LOOP (IF (NOT test)
               (EXIT))                  ; Hygienically renamed.
           body ...))))@end lisp

@noindent
Instead, a transformer must be written to not hygienically rename
@code{exit} in the output:

@lisp
(define-syntax loop-while
  (lambda (form rename compare)
    (let ((test (cadr form))
          (body (cddr form)))
      `(,(rename 'LOOP)
         (,(rename 'IF) (,(rename 'NOT) ,test)
           (EXIT))                      ; Not hygienically renamed.
         ,@@body)))
  (LOOP IF NOT))@end lisp

To understand the necessity of annotating macros with the list of
auxiliary names they use, consider the following definition of the
@code{delay} form, which transforms @code{(delay @var{exp})} into
@code{(make-promise (lambda () @var{exp}))}, where @code{make-promise}
is some non-exported procedure defined in the same module as the
@code{delay} macro:

@lisp
(define-syntax delay
  (lambda (form rename compare)
    (let ((exp (cadr form)))
      `(,(rename 'MAKE-PROMISE) (,(rename 'LAMBDA) () ,exp)))))@end lisp

@noindent
This preserves hygiene as necessary, but, while the compiler can know
whether @code{make-promise} is @emph{exported} or not, it cannot in
general determine whether @code{make-promise} is @emph{local}, @ie{}
not accessible in any way whatsoever, even in macro output, from any
other modules.  In this case, @code{make-promise} is @emph{not} local,
but the compiler cannot in general know this, and it would be an
unnecessarily heavy burden on the compiler, the linker, and related
code-processing systems to assume that all bindings are not local.  It
is therefore better@footnote{However, the current compiler in Scheme48
does not require this, though the static linker does.} to annotate such
definitions with the list of auxiliary names used by the transformer:

@lisp
(define-syntax delay
  (lambda (form rename compare)
    (let ((exp (cadr form)))
      `(,(rename 'MAKE-PROMISE) (,(rename 'LAMBDA) () ,exp))))
  (MAKE-PROMISE LAMBDA))@end lisp
